﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using IfacesEnumsStructsClasses;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Windows.Forms;
//浏览器扩展
namespace csExWB
{
    public partial class cEXWB
    {
        #region 页面资源

        /// <summary>
        /// 获得页面所有图片,不重复,包括所有frames中的
        /// </summary>
        public List<IfacesEnumsStructsClasses.IHTMLImgElement> AllImages
        {
            get
            {
                List<IfacesEnumsStructsClasses.IHTMLImgElement> imagelist = new List<IfacesEnumsStructsClasses.IHTMLImgElement>();
                foreach (IfacesEnumsStructsClasses.IHTMLElement img in this.GetImages(true))
                {
                    bool ishave = false;
                    foreach (IfacesEnumsStructsClasses.IHTMLImgElement ele in imagelist)
                    {
                        if (ele.src == ((IfacesEnumsStructsClasses.IHTMLImgElement)img).src)
                        {
                            ishave = true;
                            break;
                        }
                    }
                    if (!ishave)
                    {
                        imagelist.Add((IfacesEnumsStructsClasses.IHTMLImgElement)img);
                    }
                }
                foreach (IfacesEnumsStructsClasses.IWebBrowser2 frame in AllFrames)
                {
                    IfacesEnumsStructsClasses.IHTMLDocument2 doc = frame.Document as IfacesEnumsStructsClasses.IHTMLDocument2;
                    IfacesEnumsStructsClasses.IHTMLElementCollection images = doc.images as IfacesEnumsStructsClasses.IHTMLElementCollection;
                    foreach (IfacesEnumsStructsClasses.IHTMLElement image in images)
                    {
                        bool ishave = false;
                        foreach (IfacesEnumsStructsClasses.IHTMLImgElement ele in imagelist)
                        {
                            if (ele.src == ((IfacesEnumsStructsClasses.IHTMLImgElement)image).src)
                            {
                                ishave = true;
                                break;
                            }
                        }
                        if (!ishave)
                        {
                            imagelist.Add((IfacesEnumsStructsClasses.IHTMLImgElement)image);
                        }
                    }
                }
                return imagelist;
            }
        }
        /// <summary>
        /// 获得页面所有脚本资源
        /// </summary>
        public List<IfacesEnumsStructsClasses.IHTMLScriptElement> AllScripts
        {
            get
            {
                List<IfacesEnumsStructsClasses.IHTMLScriptElement> scriptlist = new List<IfacesEnumsStructsClasses.IHTMLScriptElement>();
                foreach (IfacesEnumsStructsClasses.IWebBrowser2 frame in AllWebBrowser)
                {
                    IfacesEnumsStructsClasses.IHTMLDocument2 doc = frame.Document as IfacesEnumsStructsClasses.IHTMLDocument2;
                    IfacesEnumsStructsClasses.IHTMLElementCollection scripts = doc.scripts as IfacesEnumsStructsClasses.IHTMLElementCollection;

                    foreach (IfacesEnumsStructsClasses.IHTMLElement script in scripts)
                    {
                        bool ishave = false;
                        foreach (IfacesEnumsStructsClasses.IHTMLScriptElement ele in scriptlist)
                        {
                            if (ele.src == ((IfacesEnumsStructsClasses.IHTMLScriptElement)script).src)
                            {
                                ishave = true;
                                break;
                            }
                        }
                        if (!ishave)
                        {
                            scriptlist.Add((IfacesEnumsStructsClasses.IHTMLScriptElement)script);
                        }
                    }
                }
                return scriptlist;
            }
        }
        /// <summary>
        /// 页面所有样式资源文件
        /// </summary>
        public List<IfacesEnumsStructsClasses.IHTMLStyleSheet> AllStyles
        {
            get
            {
                List<IfacesEnumsStructsClasses.IHTMLStyleSheet> stylelist = new List<IfacesEnumsStructsClasses.IHTMLStyleSheet>();
                foreach (IfacesEnumsStructsClasses.IWebBrowser2 frame in AllWebBrowser)
                {
                    IfacesEnumsStructsClasses.IHTMLDocument2 doc = frame.Document as IfacesEnumsStructsClasses.IHTMLDocument2;
                    IfacesEnumsStructsClasses.IHTMLStyleSheetsCollection styles = (IfacesEnumsStructsClasses.IHTMLStyleSheetsCollection)doc.styleSheets;
                    foreach (IfacesEnumsStructsClasses.IHTMLStyleSheet style in styles)
                    {
                        stylelist.Add(style);
                    }
                }
                return stylelist;
            }
        }
        /// <summary>
        /// 获得页面所有背景图片url列表 url地址,包括框架页
        /// </summary>
        public List<string> AllBackgroundImagesUrl
        {
            get
            {
                List<string> imagelist = new List<string>();

                foreach (IfacesEnumsStructsClasses.IWebBrowser2 frame in this.AllWebBrowser)
                {
                    OneWebBrowserBackgroundImagesUrls(frame,imagelist);
                }
                return imagelist;
            }
        }
        /// <summary>
        /// 返回当前浏览器背景图片,不包括框架页
        /// </summary>
        public List<string> WebBrowserBackgroundImagesUrl
        {
            get
            {
                List<string> imagelist = new List<string>();
                IfacesEnumsStructsClasses.IWebBrowser2 frame = this.WebbrowserObject;
                OneWebBrowserBackgroundImagesUrls(frame,imagelist);
                return imagelist;
            }
        }
        public void OneWebBrowserBackgroundImagesUrls(IfacesEnumsStructsClasses.IWebBrowser2 frame,List<string> imagelist)
        {
            IfacesEnumsStructsClasses.IHTMLDocument2 doc = frame.Document as IfacesEnumsStructsClasses.IHTMLDocument2;
            IfacesEnumsStructsClasses.IHTMLElementCollection all = doc.all as IfacesEnumsStructsClasses.IHTMLElementCollection;
            foreach (IfacesEnumsStructsClasses.IHTMLElement2 ele in all)
            {
                IfacesEnumsStructsClasses.IHTMLCurrentStyle sty = ele.currentStyle as IfacesEnumsStructsClasses.IHTMLCurrentStyle;
                if (sty.backgroundImage != "none")
                {
                    bool ishave = false;
                    foreach (string ele0 in imagelist)
                    {
                        if (ele0 == (System.Text.RegularExpressions.Regex.Replace(sty.backgroundImage, "(url\\()\\\"|\"\\)", "")))
                        {
                            ishave = true;
                            break;
                        }
                    }
                    if (!ishave)
                    {
                        imagelist.Add(System.Text.RegularExpressions.Regex.Replace(sty.backgroundImage, "(url\\()\\\"|\"\\)", ""));
                    }
                }
            }
        }

        /// <summary>
        /// 返回所有flash url地址
        /// </summary>
        public List<string> AllFlashsUrl
        {
            get
            {
                List<string> flashlist = new List<string>();
                foreach (IfacesEnumsStructsClasses.IHTMLWindow2 win in this.AllWebBrowser)
                {
                    IfacesEnumsStructsClasses.IHTMLDocument3 doc3 = win.document as IfacesEnumsStructsClasses.IHTMLDocument3;
                    IfacesEnumsStructsClasses.IHTMLElementCollection objects1 = doc3.getElementsByTagName("object") as IfacesEnumsStructsClasses.IHTMLElementCollection;
                    foreach (IfacesEnumsStructsClasses.IHTMLElement flash1 in objects1)
                    {
                        if (flash1.getAttribute("classid", 0).ToString().ToLower() == "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000")
                        {
                            bool ishave = false;
                            foreach (string ele in flashlist)
                            {
                                if (ele == flash1.getAttribute("movie", 0).ToString())
                                {
                                    ishave = true;
                                    break;
                                }
                            }
                            if (!ishave)
                            {
                                flashlist.Add(flash1.getAttribute("movie", 0).ToString());
                            }
                        }
                    }
                }
                return flashlist;
            }
        }
        /// <summary>
        /// 返回所有webbrowser对象,包括当前以及所有frame中的
        /// </summary>
        public List<IfacesEnumsStructsClasses.IWebBrowser2> AllWebBrowser
        {
            get
            {
                List<IfacesEnumsStructsClasses.IWebBrowser2> result = this.AllFrames;
                result.Add(this.WebbrowserObject);
                return result;
            }
        }
        public List<IfacesEnumsStructsClasses.IWebBrowser2> AllFrames
        {
            get
            {
                List<IfacesEnumsStructsClasses.IWebBrowser2> _FrameList = new List<IfacesEnumsStructsClasses.IWebBrowser2>();
                foreach (IfacesEnumsStructsClasses.IWebBrowser2 wb in this.GetFrames())
                {
                    IterativeFrames(wb, _FrameList);
                }
                return _FrameList;
            }
        }
        /// <summary>
        /// 递归获得所有frame
        /// </summary>
        /// <param name="win"></param>
        /// <param name="_FrameList"></param>
        private void IterativeFrames(IfacesEnumsStructsClasses.IWebBrowser2 win, List<IfacesEnumsStructsClasses.IWebBrowser2> _FrameList)
        {
            _FrameList.Add(win);
            foreach (IfacesEnumsStructsClasses.IWebBrowser2 wb1 in this.GetFrames(win))
            {
                IterativeFrames(wb1, _FrameList);
            }
        }

        #endregion
        /// <summary>
        /// 获得浏览器抓屏图片对象
        /// </summary>
        /// <param name="sFileName"></param>
        /// <param name="pixFormat"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public Bitmap GetBrowserImage(System.Drawing.Imaging.PixelFormat pixFormat)
        {
            if (m_WBWebBrowser2 == null) return null;
            Bitmap bmp = null;
            try
            {
                this.ScrollBarsEnabled = false;
                //Get doc2, doc3, and viewobject
                IHTMLDocument2 pDoc2 = m_WBWebBrowser2.Document as IHTMLDocument2;
                if (pDoc2 == null) return null;
                IHTMLDocument3 pDoc3 = m_WBWebBrowser2.Document as IHTMLDocument3;
                if (pDoc3 == null) return null;
                IViewObject pViewObject = pDoc2 as IViewObject;
                if (pViewObject == null) return null;

                IHTMLBodyElement pBody = null;
                IHTMLElement pElem = null;
                IHTMLElement2 pBodyElem = null;
                IHTMLStyle pStyle = null;
                string strStyle;
                int bodyHeight = 0;
                int bodyWidth = 0;
                int rootHeight = 0;
                int rootWidth = 0;
                int height = 0;
                int width = 0;

                //get the IHtmlelement
                pElem = pDoc2.body;

                //Get the IHTMLStyle
                if (pElem != null)
                    pStyle = pElem.style;

                //Get the borderstyle so we can reset it
                strStyle = pStyle.borderStyle;
                //Hide 3D border
                pStyle.borderStyle = "none";
                pBody = pElem as IHTMLBodyElement;
                //No scrollbars
                if (pBody != null)
                    pBody.scroll = "no";

                //Get root scroll h + w
                //QI for IHTMLElement2
                pBodyElem = pElem as IHTMLElement2;
                if (pBodyElem != null)
                {
                    bodyWidth = pBodyElem.scrollWidth;
                    bodyHeight = pBodyElem.scrollHeight;
                }

                //release
                pElem = null;
                pBodyElem = null;
                //Get docelem
                pElem = pDoc3.documentElement;
                //QI for IHTMLElement2
                if (pElem != null)
                {
                    pBodyElem = pElem as IHTMLElement2;
                    //Get scroll H + W
                    if (pBodyElem != null)
                    {
                        rootWidth = pBodyElem.scrollWidth;
                        rootHeight = pBodyElem.scrollHeight;
                    }
                    //calc actual W + H
                    width = rootWidth > bodyWidth ? rootWidth : bodyWidth;
                    height = rootHeight > bodyHeight ? rootHeight : bodyHeight;
                }
                //Set up a rect
                tagRECT rWPos = new tagRECT(0, 0, width, height);

                //Size browser
                if (m_WBOleInPlaceObject != null)
                    m_WBOleInPlaceObject.SetObjectRects(ref rWPos, ref rWPos);

                //Create bmp
                bmp = new Bitmap(width, height, pixFormat);

                //draw
                int hr = Hresults.S_FALSE;
                using (Graphics gr = Graphics.FromImage(bmp))
                {
                    //get hdc
                    IntPtr hdc = gr.GetHdc();
                    hr = pViewObject.Draw(
                        (uint)DVASPECT.DVASPECT_CONTENT,
                        (int)-1, m_NullPointer, m_NullPointer,
                        m_NullPointer, hdc, ref rWPos, ref rWPos,
                        m_NullPointer, (uint)0);
                    gr.ReleaseHdc(hdc);
                }

                //reset
                this.SetLocation();
                if (!string.IsNullOrEmpty(strStyle))
                    pStyle.borderStyle = strStyle;
                if (pBody != null)
                    pBody.scroll = "auto";

                if (hr == Hresults.S_OK)
                {
                    //save
                    return bmp;
                }
                else
                { return null; }
                //bmp.Dispose();
                //bmp = null;
            }
            finally
            {
                this.ScrollBarsEnabled = true;
                //if (bmp != null)
                //bmp.Dispose();
            }
        }


        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            //base.OnPaintBackground(pevent);
        }
        private string UrlToFilePath(string url)
        {
            string path = url;

            if (url.StartsWith("file", false, System.Globalization.CultureInfo.CurrentCulture))
            {
                path = url.Substring(8, url.Length - 8);
                path = path.Replace('/', '\\');
                path = path.Replace("%20", " ");
            }
            return path;

        }
        /// <summary>
        /// 返回当前路径,主要用于本地路径
        /// </summary>
        public string CurrentPath
        {
            get { return UrlToFilePath(this.LocationUrl); }
        }
        /// <summary>
        /// 获得向上路径
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private string GetUpPath(string url)
        {
            string uppath = url;
            uppath = UrlToFilePath(url);
            int i = uppath.LastIndexOf('/');
            if (i == -1) { i = uppath.LastIndexOf('\\'); }
            if (i == uppath.Length - 1)
            {
                uppath = uppath.Substring(0, uppath.Length - 2);
                i = uppath.LastIndexOf('/');
                if (i == -1) { i = uppath.LastIndexOf('\\'); }
                uppath = uppath.Substring(0, i + 1);
            }
            else
            {
                uppath = uppath.Substring(0, i + 1);
            }

            return uppath;
        }
        /// <summary>
        /// 向上
        /// </summary>
        public void NavigateUp()
        {

            string url = this.LocationUrl;
            url = GetUpPath(url);
            if (this.LocationUrl.StartsWith("file"))
            {
                if (System.IO.Directory.Exists(url))
                {
                    this.Navigate(url);
                }
            }
            else
            {
                if (url.IndexOf('.') >= 0)
                {
                    this.Navigate(url);
                }
                
            }


        }
        /// <summary>
        /// 是否可以向上
        /// </summary>
        public bool CanUp
        {
            get 
            {
                bool canup = false;
                string url = this.LocationUrl;
                url = GetUpPath(url);
                if (this.LocationUrl.StartsWith("file"))
                {
                    if (System.IO.Directory.Exists(url))
                    {
                        canup= true;
                    }
                }
                else
                {
                    if (url.IndexOf('.') >=0)
                    {
                        canup = true;
                    }
                }
                return canup;
            }
        }
        /// <summary>
        /// 是否是本地路径
        /// </summary>
        public bool IsLocalPath
        {
            get 
            {
                bool result = false;
                if (this.LocationUrl.StartsWith("file"))
                {
                    result = true;
                }
                return result;
            }
        }
    }
}
